package com.yishe.biz.wx;

import com.yishe.biz.mysql.WxContinueSignRewardBiz;
import com.yishe.biz.mysql.WxCouponAccountBiz;
import com.yishe.biz.mysql.WxSignHistoryBiz;
import com.yishe.biz.mysql.WxUserMemberInfoBiz;
import com.yishe.biz.mysql.WxUserSignInBiz;
import com.yishe.constant.WxConstants;
import com.yishe.entites.mysql.WxContinueSignReward;
import com.yishe.entites.mysql.WxCouponAccount;
import com.yishe.entites.mysql.WxSignHistory;
import com.yishe.entites.mysql.WxUserMemberInfo;
import com.yishe.entites.mysql.WxUserSignIn;
import com.yishe.entites.mysql.YsMemberType;
import com.yishe.entites.vo.SignVo;
import com.yishe.mapper.mysql.WxSignHistoryMapper;
import com.yishe.mapper.mysql.YsMemberTypeMapper;
import com.yishe.utils.CommonUtils;
import com.yishe.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.checkerframework.checker.units.qual.C;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author : chusifeng
 * @version :1.0
 * @date :Create in 2021/4/17 13:47
 * @description: 微信签到功能Service
 * @package com.yishe.biz.mysql
 * @className WxSignBiz
 */
@Service
@Slf4j
public class WxSignBiz {

    @Resource
    private WxUserSignInBiz wxUserSignInBiz;
    @Resource
    private WxSignHistoryMapper wxSignHistoryMapper;
    @Resource
    private YsMemberTypeMapper ysMemberTypeMapper;
    @Resource
    private WxSignHistoryBiz wxSignHistoryBiz;
    @Resource
    private WxUserMemberInfoBiz wxUserMemberInfoBiz;
    @Resource
    private WxContinueSignRewardBiz wxContinueSignRewardBiz;
    @Resource
    private WxCouponAccountBiz wxCouponAccountBiz;

    /**
     * create by: chusifeng
     * Create in 2021/4/17 21:39
     * Description:获取历史签到数据
     * <p>Example</p>
     */
    public SignVo getSignHistory(Map<String, String> param) throws ParseException {
        String account = param.get("account");
        String month_year = param.get("date");
        SignVo signVoOut = new SignVo();

        WxUserSignIn wxUserSignIn = new WxUserSignIn();
        wxUserSignIn.setWxAccount(account);
        //当月月份
        wxUserSignIn.setSignMonthTime(DateUtil.getNow(DateUtil.YYYY_MM));
        wxUserSignIn = wxUserSignInBiz.selectOne(wxUserSignIn);
        WxSignHistory wxSignHistory = new WxSignHistory();
        wxSignHistory.setWxAccount(account);
        if (null == wxUserSignIn) {
            //输出页面赋值
            signVoOut.setMonthSign(0);
            signVoOut.setTotalSign(0);
            signVoOut.setContinuMonthSign(0);
            signVoOut.setSignLastDays(0);
            signVoOut.setIsSigned(false);
        } else {
            wxSignHistory.setSignDate(DateUtil.getNowDate(DateUtil.YYYY_MM_DD));
            WxSignHistory history = wxSignHistoryBiz.selectOne(wxSignHistory);
            if (null != history) {
                signVoOut.setIsSigned(true);
            }
            //查询昨天是否签到了
            Calendar c = Calendar.getInstance();
            c.setTime(new Date());
            c.add(Calendar.DATE, -1);

            wxSignHistory.setSignDate(DateUtil.getDateByDate(c.getTime(), DateUtil.YYYY_MM_DD));
            wxSignHistory = wxSignHistoryBiz.selectOne(wxSignHistory);
            if (null != wxSignHistory) {
                //昨天签到了
                Calendar calendar = Calendar.getInstance();
                int data_of_month = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
                if (1 == data_of_month) {
                    signVoOut.setContinuMonthSign(1);
                } else {
                    //累加一下本月连续签到数量和总共签到数量
                    signVoOut.setContinuMonthSign(wxUserSignIn.getMonthSignTotal());
                }
                signVoOut.setSignLastDays(wxUserSignIn.getContinuSignTotal());
            }
        }
        //总共签到天数
        Integer total = wxSignHistoryMapper.getAllSignDays(account);
        signVoOut.setTotalSign(total);
        //赋值输出本月签到的数字
        String startTime = month_year + "-01";
        String end = DateUtil.executeEndDay(month_year);
        String endTime = month_year + "-" + end;
        param.put("startTime", startTime);
        param.put("endTime", endTime);
        List<WxSignHistory> signHistories = wxSignHistoryMapper.getListByAccountAndDate(param);
        signVoOut.setMonthSign(signHistories.size());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        int[] idays = signHistories.stream().mapToInt(his -> Integer.parseInt(sdf.format(his.getSignDate()).substring(8, 10))).toArray();
        List<Integer> idaysList = new ArrayList<>(idays.length);
        for (int iday : idays) {
            idaysList.add(iday);
        }
        Collections.sort(idaysList);
        signVoOut.setSignDays(idaysList);
        return signVoOut;
    }

    /**
     * 签到
     *
     * @param signVoInput 签到对象
     * @return
     */
    @Transactional(value = "mysqlTransactionManager", rollbackFor = Exception.class)
    public SignVo createSign(SignVo signVoInput) throws Exception {
        if (!signVoInput.getIsSigned()) {
            return signVoInput;
        }
        //存在记录则直接返回提示
        WxSignHistory wxSignHistory = new WxSignHistory();
        wxSignHistory.setWxAccount(signVoInput.getAccount());
        wxSignHistory.setOpenid(signVoInput.getOpenid());
        wxSignHistory.setSignDate(DateUtil.getNowDate(DateUtil.YYYY_MM_DD));
        WxSignHistory history = wxSignHistoryBiz.selectOne(wxSignHistory);
        if (null != history) {
            throw new RuntimeException("已存在数据!");
        }
        //插入签到历史表数据
        wxSignHistoryBiz.insert(wxSignHistory);
        //处理连续签到额外奖励
        //当月签到
        WxUserSignIn wxUserSignIn = new WxUserSignIn();
        wxUserSignIn.setWxAccount(signVoInput.getAccount());
        //当月月份
        wxUserSignIn.setSignMonthTime(DateUtil.getNow(DateUtil.YYYY_MM));
        //当月的签到记录数据
        wxUserSignIn = wxUserSignInBiz.selectOne(wxUserSignIn);
        if (null == wxUserSignIn) {
            wxUserSignIn = new WxUserSignIn();
            //输出页面赋值
            signVoInput.setMonthSign(1);
            signVoInput.setTotalSign(1);
            //本月未签到，初始化数据主表
            wxUserSignIn.setWxAccount(signVoInput.getAccount());
            wxUserSignIn.setOpenid(signVoInput.getOpenid());
            wxUserSignIn.setMonthSignTotal(1);
            wxUserSignIn.setContinuSignTotal(1);
            wxUserSignIn.setSignTotal(1);
            wxUserSignIn.setTodaySign(WxConstants.IS_SIGNED);
            wxUserSignIn.setYesterdaySign(WxConstants.IS_SIGNED);
            wxUserSignIn.setSignMonthTime(DateUtil.getNow(DateUtil.YYYY_MM));
            wxUserSignInBiz.insert(wxUserSignIn);
            signVoInput.setMonthSign(1);
            signVoInput.setContinuMonthSign(1);
            signVoInput.setSignLastDays(1);

        } else {
            //今天已签到
            wxUserSignIn.setTodaySign(WxConstants.IS_SIGNED);
            //查询昨天是否签到了
            wxSignHistory = new WxSignHistory();
            wxSignHistory.setWxAccount(wxUserSignIn.getWxAccount());
            wxSignHistory.setSignDate(DateUtil.getDate(signVoInput.getYestodayTime(), DateUtil.YYYY_MM_DD));
            wxSignHistory = wxSignHistoryBiz.selectOne(wxSignHistory);
            if (null != wxSignHistory) {
                //昨天签到了
                Calendar calendar = Calendar.getInstance();
                int data_of_month = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
                if (1 == data_of_month) {
                    wxUserSignIn.setMonthSignTotal(1);
                    signVoInput.setContinuMonthSign(1);
                } else {
                    int mongthSigns = wxUserSignIn.getMonthSignTotal();
                    wxUserSignIn.setMonthSignTotal(mongthSigns + 1);
                    //累加一下本月签到数量和总共签到数量
                    signVoInput.setContinuMonthSign(mongthSigns + 1);
                }
                int signTotals = wxUserSignIn.getContinuSignTotal();
                wxUserSignIn.setContinuSignTotal(signTotals + 1);
                signVoInput.setSignLastDays(signTotals + 1);
                wxUserSignIn.setYesterdaySign(WxConstants.IS_SIGNED);
            } else {
                wxUserSignIn.setYesterdaySign(WxConstants.NOT_SIGNED);
                wxUserSignIn.setContinuSignTotal(1);
                wxUserSignIn.setMonthSignTotal(1);
                signVoInput.setSignLastDays(1);
                signVoInput.setContinuMonthSign(1);

            }
        }
        //总共签到天数
        Integer total = wxSignHistoryMapper.getAllSignDays(signVoInput.getAccount());
        wxUserSignIn.setSignTotal(total);
        //处理积分奖励
        additionalReward(signVoInput.getOpenid(), wxUserSignIn);
        signVoInput.setTotalSign(total);
        //赋值输出本月签到的数字
        String month_year = DateUtil.getNow(DateUtil.YYYY_MM);
        String startTime = month_year + "-01";
        String end = DateUtil.executeEndDay(month_year);
        String endTime = month_year + "-" + end;
        Map<String, String> param = new HashMap<>(3);
        param.put("startTime", startTime);
        param.put("endTime", endTime);
        param.put("account", wxUserSignIn.getWxAccount());
        List<WxSignHistory> signHistories = wxSignHistoryMapper.getListByAccountAndDate(param);
        signVoInput.setMonthSign(signHistories.size());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        int[] idays = signHistories.stream().mapToInt(his -> {
                Date d = his.getSignDate();
                String formatDate = sdf.format(d);
                return Integer.parseInt(formatDate.substring(8, 10));
            }
        ).toArray();
        List<Integer> idaysList = new ArrayList<>(idays.length);
        for (int iday : idays) {
            idaysList.add(iday);
        }
        Collections.sort(idaysList);
        signVoInput.setSignDays(idaysList);
        wxUserSignInBiz.updateById(wxUserSignIn);
        return signVoInput;
    }

    /**
     * 额外签到奖励
     */
    @Transactional(value = "mysqlTransactionManager", rollbackFor = Exception.class)
    public void additionalReward(String openid, WxUserSignIn wxUserSignIn) {
        //本次签到累计积分
        WxUserMemberInfo wxUserMemberInfo = new WxUserMemberInfo();
        wxUserMemberInfo.setOpenid(openid);
        wxUserMemberInfo.setWxAccount(wxUserSignIn.getWxAccount());
        wxUserMemberInfo = wxUserMemberInfoBiz.selectOne(wxUserMemberInfo);
        if (null == wxUserMemberInfo) {
            //没有任何充值之类的积分奖励使用，首次签到使用
            wxUserMemberInfo = new WxUserMemberInfo();
            wxUserMemberInfo.setJfTotal(1);
            wxUserMemberInfo.setJfCurrent(1);
            wxUserMemberInfo.setMemberCurLevel(WxConstants.MemberType.BRONZE.getTypeCode());
            wxUserMemberInfo.setMemberGetTime(new Date());
            wxUserMemberInfoBiz.insert(wxUserMemberInfo);
        } else {
            //积分增加，1-7天，连续签到的天数值对应积分值
            int continueDays = wxUserSignIn.getContinuSignTotal();
            //基本积分奖励
            int rewardJf = 1;

//            rewardJf = Math.min(continueDays, 7);
            wxUserMemberInfo.setJfTotal(wxUserMemberInfo.getJfTotal() + rewardJf);
            wxUserMemberInfo.setJfCurrent(wxUserMemberInfo.getJfCurrent() + rewardJf);
            //连续签到满30奖50，依次类推
            if (continueDays % 30 == 0) {
                wxUserMemberInfo.setJfTotal(wxUserMemberInfo.getJfTotal() + 50);
                wxUserMemberInfo.setJfCurrent(wxUserMemberInfo.getJfCurrent() + 50);
            }
//            //判断是否满足升会员等级条件,获取下一等级规则
//            String nextMember = String.valueOf(Integer.parseInt(wxUserMemberInfo.getMemberCurLevel())+1);
//            YsMemberType memberType = new YsMemberType();
//            memberType.setMemberLevel(nextMember);
//            memberType = ysMemberTypeMapper.selectOne(memberType);
//            if(wxUserMemberInfo.getJfTotal()>= memberType.getMemberJfLow()) {
//                //满足规则，晋升
//                wxUserMemberInfo.setMemberCurLevel(nextMember);
//                wxUserMemberInfo.setMemberGetTime(new Date());
//            }
            //本次奖励匹配上了规则
//            WxContinueSignReward matchReward = null;
//            //所有额外积分奖励规则
//            List<WxContinueSignReward> wxContinueSignRewardList = wxContinueSignRewardBiz.selectListAll();
//            for (WxContinueSignReward continueSignReward : wxContinueSignRewardList) {
//                if (continueSignReward.getRewardDayType() == continueDays) {
//                    matchReward = continueSignReward;
//                    break;
//                }
//            }
//            if (null != matchReward) {
//                //积分还是优惠券.1积分
//                if (WxConstants.REWARD_1.equals(matchReward.getRewardType())) {
//                    rewardJf = matchReward.getRewardValue().intValue();
//                    wxUserMemberInfo.setJfTotal(wxUserMemberInfo.getJfTotal() + rewardJf);
//                    wxUserMemberInfo.setJfCurrent(wxUserMemberInfo.getJfCurrent() + rewardJf);
//                } else {
//                    //优惠券，需要往优惠券表插入记录
//                    WxCouponAccount couponAccount = new WxCouponAccount();
//                    couponAccount.setCouponno(CommonUtils.getRandomByLength(30));
//                    Date now = new Date();
//                    couponAccount.setSenddate(now);
//                    //开始使用日期，默认立刻
//                    couponAccount.setStartdate(now);
//                    couponAccount.setAmount(matchReward.getRewardValue());
//                    couponAccount.setMamount(matchReward.getMamount());
//                    couponAccount.setEndate(DateUtil.getNextDate(now,matchReward.getRewardTime(),true));
//                    couponAccount.setCouponStatus(WxConstants.COUPONSTATUS_USE);
//                    couponAccount.setCouponName(matchReward.getRewardTypeDesc());
//                    couponAccount.setOpenid(wxUserSignIn.getOpenid());
//                    wxCouponAccountBiz.insert(couponAccount);
//                }
        }
        wxUserMemberInfoBiz.updateById(wxUserMemberInfo);
    }

}
